home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
431_01
/
rserver.c
< prev
next >
Wrap
Text File
|
1995-01-06
|
23KB
|
931 lines
/*
SERVER
1. wait for request packets
2. execute request packet
3. package result
4. continue
notes:
each function is in C but calls DOS through intr().
this is clunky, i know, but it comes from a bizarre design. initially
i thought i could translate everything into C calls (open, close, etc..)
but no such luck because i had to translate the C return codes to DOS
codes which was much too much trouble. later, it turns out the that
_doserrno holds the DOS return code, but i had already re-worked
my code.
this is almost entirely CLIENT controlled. the server makes few
decisions. all filenames are translated at the client, etc...
*/
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <dir.h>
#include <string.h>
#include <assert.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <errno.h>
#include <conio.h>
#include <time.h>
#include "ifs.h"
#include "comio.h"
#include "crc32.h"
#include "svr0.h"
#include "myalloc.h"
#include "rifs.h"
#include "rclient.h"
#include "local.h"
unsigned _stklen = 512; /* minimal local stack */
BYTE *SDA; /* swappable data area */
WORD SDA_maxsize; /* size of SDA */
WORD SDA_minsize; /* min. size of SDA */
BYTE *SDA_DOSBUSY; /* DOS busy flag */
BYTE *CDS_base; /* current directory structure */
WORD CDS_EntrySize; /* # of bytes per entry */
WORD CDS_ct; /* number of entries */
WORD CDS_TotalSize; /* total number of bytes */
/*************************************************************************
*************************************************************************
SERVER
*************************************************************************
*************************************************************************/
XMITBUF *iobuf; /* send / recieve buffer(s) */
XMITBUF *iobufptr; /* pointer to recieve buffer */
BYTE *lcl_SDA; /* local copy of SDA */
CDS *lcl_CDS; /* local copy of CDS */
LOCAL int datasize = BLOCKSIZE; /* size of packet data */
LOCAL int state; /*
used by ASYNC for state info:
0 = looking for 'K'
1 = looking for 'Y'
2 = storing ALL incoming
3 = waiting to finish server request
*/
LOCAL IFS_STAT IFS_stat; /* struct for keeping statistics */
BOOL background=TRUE; /* TRUE if running in background, else FALSE */
LOCAL unsigned openpsp[MAXOPEN];
#define SETRESULT(a) {iobufptr->length=0; iobufptr->cmd=a;}
/*
remove directory
ASCIIz = name of directory to remove
*/
LOCAL void svr_rmdir(XMITBUF *iobuf)
{
if (rmdir(iobuf->data)) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
}
/*
make directory
ASCIIz = name of directory to create
*/
LOCAL void svr_mkdir(XMITBUF *iobuf)
{
if (mkdir(iobuf->data)) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
}
/*
change directory
ASCIIz = name of directory to change
*/
LOCAL void svr_chdir(XMITBUF *iobuf)
{
if (chdir(iobuf->data)) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
}
/*
close file
WORD : handle of file to close
*/
LOCAL void svr_closefile(XMITBUF *iobuf)
{
unsigned cascade_error;
int handle = *(unsigned *) iobuf->data;
if (setftime(handle, (struct ftime *) (iobuf->data+2)))
cascade_error = _doserrno;
else
cascade_error = 0;
if (close(handle)) {
SETRESULT(_doserrno);
} else
SETRESULT(cascade_error);
if (handle < MAXOPEN)
openpsp[handle]=0;
}
/*
commit file buffers
WORD : handle of file to commit
*/
LOCAL void svr_commitfile(XMITBUF *iobuf)
{
SETRESULT(0);
}
/*
read from a file
WORD : handle
DWORD : position
WORD : length
returns
WORD : number of bytes read
BYTE[] : bytes
*/
LOCAL void svr_readfile(XMITBUF *iobuf)
{
int handle=*(int *) iobuf->data;
long pos= *(long *) (iobuf->data+2);
int len= *(int *) (iobuf->data+6);
int rlen;
lseek(handle, pos, SEEK_SET);
errno = 0;
_doserrno = 0;
rlen = read(handle, iobuf->data+2, len);
if (rlen != len) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
*(int *) iobuf->data=rlen;
iobuf->length=2+rlen;
}
/*
write to file
WORD : file handle
DWORD : position
WORD : length
BYTES[] : data
return
WORD : bytes written, 0xffff = error
*/
LOCAL void svr_writefile(XMITBUF *iobuf)
{
int handle=*(int *) iobuf->data;
long pos= *(long *) (iobuf->data+2);
int len= *(int *) (iobuf->data+6);
int wlen;
lseek(handle, pos, SEEK_SET);
errno = 0;
_doserrno = 0;
wlen = write(handle, iobuf->data+8, len);
if (wlen != len) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
*(int *) iobuf->data=wlen;
iobuf->length=2;
}
/*
lock file bytes
WORD : handle
DWORD : position
DWORD : length
*/
LOCAL void svr_lockfile(XMITBUF *iobuf)
{
int handle=*(int *) iobuf->data;
long pos = *(long *) (iobuf->data + 2);
long len = *(long *) (iobuf->data + 6);
if (lock(handle, pos, len)) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
}
/*
lock/unlock file bytes
WORD : handle
WORD : function (0 = lock / 1 = unlock)
DWORD : position
DWORD : size
*/
LOCAL void svr_unlockfile(XMITBUF *iobuf)
{
int handle=*(int *) iobuf->data;
int fn =*(int *) (iobuf->data + 2);
long pos = *(long *) (iobuf->data + 4);
long len = *(long *) (iobuf->data + 8);
int result;
result = (fn) ? lock(handle, pos, len) : unlock(handle, pos, len);
if (result) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
}
/*
get free space
BYTE : drive number (0 = a)
return
struct dfree
*/
LOCAL void svr_getspace(XMITBUF *iobuf)
{
struct dfree *df=(void *) iobuf->data;
getdfree(iobuf->data[0], df);
if (df->df_sclus == 0xffff) {
SETRESULT(_doserrno);
} else {
SETRESULT(0);
}
iobuf->length = sizeof(*df);
}
/*
set file attribute
WORD : attribute
ASCIIz : filename
*/
LOCAL void svr_setattr(XMITBUF *iobuf)
{
if (chmod(iobuf->data+2, *(int *) iobuf->data)) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
}
/*
return file attribute
ASCIIz : filename
return
WORD : attribute
*/
LOCAL void svr_getattr(XMITBUF *iobuf)
{
struct REGPACK regs;
regs.r_ax=0x4300;
regs.r_dx=FP_OFF(iobuf->data);
regs.r_ds=FP_SEG(iobuf->data);
intr(0x21, ®s);
if (regs.r_flags & 0x01) {
SETRESULT(regs.r_ax);
} else {
SETRESULT(0);
*(int *) iobuf->data=regs.r_cx;
iobuf->length=2;
}
}
/*
rename file
ASCIIz : old name
ASCIIz : new name
*/
LOCAL void svr_renamefile(XMITBUF *iobuf)
{
if (rename(iobuf->data, iobuf->data+strlen(iobuf->data)+1)) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
}
/*
delete file
ASCIIz : filename
*/
LOCAL void svr_deletefile(XMITBUF *iobuf)
{
if (unlink(iobuf->data)) {
SETRESULT(_doserrno);
} else
SETRESULT(0);
}
/*
open file
WORD : open mode
ASCIIz : filename
return
WORD : file handle
WORD : file attribute
WORD : file time
WORD : file date
DWORD : file length
*/
LOCAL void svr_openfile(XMITBUF *iobuf)
{
struct REGPACK regs;
/*
call DOS open
*/
regs.r_ax=0x3d00 | ((*(int *) iobuf->data) & 0xff);
regs.r_dx=FP_OFF(iobuf->data)+2;
regs.r_ds=FP_SEG(iobuf->data);
intr(0x21, ®s);
if (regs.r_flags & 0x01) {
SETRESULT(regs.r_ax);
} else {
SETRESULT(0);
if (regs.r_ax < MAXOPEN)
openpsp[regs.r_ax]=iobuf->process_id;
*(int *) iobuf->data=regs.r_ax;
*(int *) (iobuf->data+2)=_chmod(iobuf->data+2, 0);
regs.r_bx=*(int *) iobuf->data